﻿/***************************************************************************
 *   Copyright (c) 2008 Jürgen Riegel <juergen.riegel@web.de>              *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 of the License, or (at your option) any later version.      *
 *                                                                         *
 *   This library  is distributed in the hope that it will be useful,      *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/


#include "pch.h"
#include <boost_signals2.hpp>
#include <qglobal.h>
#include <App/Document.h>
#include "Gui/Command.h"
#include "Part/App/Attacher.h"
#include "Sketcher/App/Constraint.h"
#include "Base/Placement.h"
#include "Gui/Selection.h"
#include "App/Application.h"
#include "Gui/Application.h"
#include <Gui/Document.h>
using namespace std;
using namespace Attacher;


/* Sketch commands =======================================================*/
DEF_STD_CMD_A(CmdSketcherNewSketch)

CmdSketcherNewSketch::CmdSketcherNewSketch()
    : Command("Sketcher_NewSketch") {
    sAppModule = "Sketcher";
    sGroup = "Sketcher";
    sMenuText = QT_TR_NOOP("Create sketch");
    sToolTipText = QT_TR_NOOP("Create a new sketch.");
    sWhatsThis = "Sketcher_NewSketch";
    sStatusTip = sToolTipText;
    sPixmap = "Sketcher_NewSketch";
}

void CmdSketcherNewSketch::activated(int iMsg) {
    Q_UNUSED(iMsg);
    Attacher::eMapMode mapmode = Attacher::mmDeactivated;
    bool bAttach = false;
    int placement = 1;
    auto Pos = Base::Placement();
    switch (placement) {
    case 0:
        Pos = Base::Placement(Base::Vector3d(0,0,0.0),Base::Rotation());// XY
        break;
        case 1:
            Pos = Base::Placement(Base::Vector3d(0,0.0,0),Base::Rotation(1.0,0.0,0.0,1.0)); // XZ
        break;
        case 2:
            Pos = Base::Placement(Base::Vector3d(0.0,0,0),Base::Rotation(1.0,1.0,1.0,1.0)); // YZ
        break;
        default:
            break;
    }
    auto sko = App::GetApplication().getActiveDocument()->addObject("Sketcher::SketchObject", "Sketch", true, nullptr, false);
    auto view = Gui::Application::Instance->activeDocument()->getViewProvider(sko);
    static_cast<Sketcher::SketchObject*>(sko)->Placement.setValue(Pos);
    Gui::Application::Instance->activeDocument()->setEdit(view);
}

bool CmdSketcherNewSketch::isActive(void) {
    if (getActiveGuiDocument())
        return true;
    else
        return false;
}

DEF_STD_CMD_A(CmdSketcherEditSketch)

CmdSketcherEditSketch::CmdSketcherEditSketch()
    : Command("Sketcher_EditSketch") {
    sAppModule = "Sketcher";
    sGroup = "Sketcher";
    sMenuText = QT_TR_NOOP("Edit sketch");
    sToolTipText = QT_TR_NOOP("Edit the selected sketch.");
    sWhatsThis = "Sketcher_EditSketch";
    sStatusTip = sToolTipText;
    sPixmap = "Sketcher_EditSketch";
}

void CmdSketcherEditSketch::activated(int iMsg) {
    // 2.编辑草图
}

bool CmdSketcherEditSketch::isActive(void) {
    return false;
}

DEF_STD_CMD_A(CmdSketcherLeaveSketch)

CmdSketcherLeaveSketch::CmdSketcherLeaveSketch()
    : Command("Sketcher_LeaveSketch") {
    sAppModule = "Sketcher";
    sGroup = "Sketcher";
    sMenuText = QT_TR_NOOP("Leave sketch");
    sToolTipText = QT_TR_NOOP("Finish editing the active sketch.");
    sWhatsThis = "Sketcher_LeaveSketch";
    sStatusTip = sToolTipText;
    sPixmap = "Sketcher_LeaveSketch";
    eType = 0;
}

void CmdSketcherLeaveSketch::activated(int iMsg) {
    // 离开草图
}

bool CmdSketcherLeaveSketch::isActive(void) {
    return false;
}

DEF_STD_CMD_A(CmdSketcherStopOperation)

CmdSketcherStopOperation::CmdSketcherStopOperation()
    : Command("Sketcher_StopOperation") {
    sAppModule = "Sketcher";
    sGroup = "Sketcher";
    sMenuText = QT_TR_NOOP("Stop operation");
    sToolTipText = QT_TR_NOOP("When in edit mode, "
        "stop the active operation "
        "(drawing, constraining, etc.).");
    sWhatsThis = "Sketcher_StopOperation";
    sStatusTip = sToolTipText;
    sPixmap = "process-stop";
    eType = 0;
}

void CmdSketcherStopOperation::activated(int iMsg) {
    //6.停止操作
}

bool CmdSketcherStopOperation::isActive(void) {
    return false;
}

DEF_STD_CMD_A(CmdSketcherReorientSketch)

CmdSketcherReorientSketch::CmdSketcherReorientSketch()
    : Command("Sketcher_ReorientSketch") {
    sAppModule = "Sketcher";
    sGroup = "Sketcher";
    sMenuText = QT_TR_NOOP("Reorient sketch...");
    sToolTipText = QT_TR_NOOP("Place the selected sketch on one of the global coordinate planes.\n"
        "This will clear the 'Support' property, if any.");
    sWhatsThis = "Sketcher_ReorientSketch";
    sStatusTip = sToolTipText;
    sPixmap = "Sketcher_ReorientSketch";
}

void CmdSketcherReorientSketch::activated(int iMsg) {
    // 
}

bool CmdSketcherReorientSketch::isActive(void) {
    return false;
}

DEF_STD_CMD_A(CmdSketcherMapSketch)

CmdSketcherMapSketch::CmdSketcherMapSketch()
    : Command("Sketcher_MapSketch") {
    sAppModule = "Sketcher";
    sGroup = "Sketcher";
    sMenuText = QT_TR_NOOP("Map sketch to face...");
    sToolTipText = QT_TR_NOOP("Set the 'Support' of a sketch.\n"
        "First select the supporting geometry, for example, a face or an edge of a solid object,\n"
        "then call this command, then choose the desired sketch.");
    sWhatsThis = "Sketcher_MapSketch";
    sStatusTip = sToolTipText;
    sPixmap = "Sketcher_MapSketch";
}

void CmdSketcherMapSketch::activated(int iMsg) {
    // 9.映射草图至
}

bool CmdSketcherMapSketch::isActive(void) {
    return false;
}

DEF_STD_CMD_A(CmdSketcherViewSketch)

CmdSketcherViewSketch::CmdSketcherViewSketch()
    : Command("Sketcher_ViewSketch") {
    sAppModule = "Sketcher";
    sGroup = "Sketcher";
    sMenuText = QT_TR_NOOP("View sketch");
    sToolTipText = QT_TR_NOOP("When in edit mode, "
        "set the camera orientation perpendicular to the sketch plane.");
    sWhatsThis = "Sketcher_ViewSketch";
    sStatusTip = sToolTipText;
    sPixmap = "Sketcher_ViewSketch";
    sAccel = "Q, P";
    eType = 0;
}

void CmdSketcherViewSketch::activated(int iMsg) {
    // 3.查看草图
}

bool CmdSketcherViewSketch::isActive(void) {
    return false;
}

DEF_STD_CMD_A(CmdSketcherValidateSketch)

CmdSketcherValidateSketch::CmdSketcherValidateSketch()
    : Command("Sketcher_ValidateSketch") {
    sAppModule = "Sketcher";
    sGroup = "Sketcher";
    sMenuText = QT_TR_NOOP("Validate sketch...");
    sToolTipText = QT_TR_NOOP("Validate a sketch by looking at missing coincidences,\n"
        "invalid constraints, degenerated geometry, etc.");
    sWhatsThis = "Sketcher_ValidateSketch";
    sStatusTip = sToolTipText;
    eType = 0;
    sPixmap = "Sketcher_ValidateSketch";
}

void CmdSketcherValidateSketch::activated(int iMsg) {
    // 8.校验草图
}

bool CmdSketcherValidateSketch::isActive(void) {
    return false;
}

DEF_STD_CMD_A(CmdSketcherMirrorSketch)

CmdSketcherMirrorSketch::CmdSketcherMirrorSketch()
    : Command("Sketcher_MirrorSketch") {
    sAppModule = "Sketcher";
    sGroup = "Sketcher";
    sMenuText = QT_TR_NOOP("Mirror sketch");
    sToolTipText = QT_TR_NOOP("Create a new mirrored sketch for each selected sketch\n"
        "by using the X or Y axes, or the origin point,\n"
        "as mirroring reference.");
    sWhatsThis = "Sketcher_MirrorSketch";
    sStatusTip = sToolTipText;
    eType = 0;
    sPixmap = "Sketcher_MirrorSketch";
}

void CmdSketcherMirrorSketch::activated(int iMsg) {
    // 5.镜像草图
}

bool CmdSketcherMirrorSketch::isActive(void) {
    return false;
}

DEF_STD_CMD_A(CmdSketcherMergeSketches)

CmdSketcherMergeSketches::CmdSketcherMergeSketches()
    : Command("Sketcher_MergeSketches") {
    sAppModule = "Sketcher";
    sGroup = "Sketcher";
    sMenuText = QT_TR_NOOP("Merge sketches");
    sToolTipText = QT_TR_NOOP("Create a new sketch from merging two or more selected sketches.");
    sWhatsThis = "Sketcher_MergeSketches";
    sStatusTip = sToolTipText;
    eType = 0;
    sPixmap = "Sketcher_MergeSketch";
}

void CmdSketcherMergeSketches::activated(int iMsg) {
    // 4.合并草图
}

bool CmdSketcherMergeSketches::isActive(void) {
    return false;
}

// Acknowledgement of idea and original python macro goes to SpritKopf:
// https://github.com/Spritkopf/freecad-macros/blob/master/clip-sketch/clip_sketch.FCMacro
// https://forum.freecadweb.org/viewtopic.php?p=231481#p231085
DEF_STD_CMD_A(CmdSketcherViewSection)

CmdSketcherViewSection::CmdSketcherViewSection()
    : Command("Sketcher_ViewSection") {
    sAppModule = "Sketcher";
    sGroup = "Sketcher";
    sMenuText = QT_TR_NOOP("View section");
    sToolTipText = QT_TR_NOOP("When in edit mode, "
        "switch between section view and full view.");
    sWhatsThis = "Sketcher_ViewSection";
    sStatusTip = sToolTipText;
    sPixmap = "Sketcher_ViewSection";
    sAccel = "Q, S";
    eType = 0;
}

void CmdSketcherViewSection::activated(int iMsg) {
    // 3.查看草图
}

bool CmdSketcherViewSection::isActive(void) {
    return false;
}

void CreateSketcherCommands(void) {
    Gui::CommandManager& rcCmdMgr =  Gui::Application::Instance->commandManager();

    rcCmdMgr.addCommand(new CmdSketcherNewSketch());
    rcCmdMgr.addCommand(new CmdSketcherEditSketch());
    rcCmdMgr.addCommand(new CmdSketcherLeaveSketch());
    rcCmdMgr.addCommand(new CmdSketcherStopOperation());
    rcCmdMgr.addCommand(new CmdSketcherReorientSketch());
    rcCmdMgr.addCommand(new CmdSketcherMapSketch());
    rcCmdMgr.addCommand(new CmdSketcherViewSketch());
    rcCmdMgr.addCommand(new CmdSketcherValidateSketch());
    rcCmdMgr.addCommand(new CmdSketcherMirrorSketch());
    rcCmdMgr.addCommand(new CmdSketcherMergeSketches());
    rcCmdMgr.addCommand(new CmdSketcherViewSection());
}
